﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DbSharp.Framework.Assertion;
using DbSharp.Framework.DbObject;

namespace DbSharp.Framework.TestEngine
{
    public class CaseTestResult
    {
        
        #region Private memebers

        private CaseTestState m_TestState = CaseTestState.NotRun;
        private List<StmtExecutionResult> m_ListStatementResult = new List<StmtExecutionResult>();
        private AssertionType m_AssertionType;
        private string m_TestName;

        #endregion

        public CaseTestResult(string testName, AssertionType assertionType)
        {
            m_TestName=testName ;
            m_AssertionType = assertionType;
        }

        public CaseTestState TestState
        {
            get { return m_TestState; }
            set { m_TestState = value; }
        }

        public List<StmtExecutionResult> ListStatementResult
        {
            get { return m_ListStatementResult; }
        }

        public string ErrorHint { get; set; }

        public bool ExportedFlag { get; set; }

        public string TargetRsltsetExportFile { get; set; }

        public string ReferRsltsetExportFile { get; set; }

        public void Reset()
        {
            this.ListStatementResult.Clear();
            ExportedFlag = false;
            TargetRsltsetExportFile = string.Empty;
            ReferRsltsetExportFile = string.Empty;
            TestState = CaseTestState.NotRun;
            ErrorHint = string.Empty;
        }

        public string ToShortString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("Case name: "+m_TestName);
            sb.AppendFormat(", State: {0}. ", m_TestState.ToString());
            if (m_AssertionType!=null)
                sb.AppendFormat(", Assertion: {0}. ", m_AssertionType.ToString());
            if ((TestState == CaseTestState.Failed) && (string.IsNullOrEmpty(ErrorHint) == false))
                sb.AppendFormat(", Error: {0}. ", ErrorHint.ToString());
            return sb.ToString();
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            
            //output summary
            sb.AppendLine("==================================================");
            sb.AppendLine("Case result summary");
            sb.AppendLine("Case name: "+m_TestName);
            sb.Append("State: ");
            sb.AppendLine(m_TestState.ToString());
            if (m_AssertionType != null)
            {
                sb.Append("Assertion: ");
                sb.AppendLine(m_AssertionType.ToString());
            }
            if ((TestState == CaseTestState.Failed) && (string.IsNullOrEmpty(ErrorHint) == false))
            {
                sb.Append("Error: ");
                sb.AppendLine(ErrorHint.ToString());
            }
            sb.Append("Exported flag: ");
            sb.AppendLine(ExportedFlag.ToString());
            sb.AppendLine("==================================================");
            sb.AppendLine();

            int statementIndex = 1;
            //output resultset 
            foreach(var item in m_ListStatementResult)
            {
                sb.AppendLine("--------------------------------------------------");
                if (item.IsTargetResultset)
                    sb.AppendLine("Target statement execution result (index="+statementIndex+")");
                else
                    sb.AppendLine("Reference statement execution result (index=" + statementIndex + ")");
                sb.AppendLine("--------------------------------------------------");
                statementIndex++;

                sb.Append("Execute time (milliseconds): ");
                sb.AppendLine(item.ExecuteMilliseconds.ToString());

                sb.Append("Fetch time (milliseconds): ");
                sb.AppendLine(item.FetchDataMilliseconds.ToString());

                sb.Append("Total time (milliseconds): ");
                sb.AppendLine(item.TotalMilliseconds.ToString());

                if (string.IsNullOrEmpty(item.ErrorMessage) == false)
                {
                    sb.Append("Error message: ");
                    sb.AppendLine(item.ErrorMessage);
                }
                sb.AppendLine();

                #region iterate each out-type scalar argument

                foreach (var scalar in item.ListScalarExecutionResult)
                {
                    sb.Append("Scalar argument: ");
                    sb.AppendLine(scalar.Argument.Name);
                    sb.Append("  Value: ");
                    if (scalar.ScalarValue != null)
                        sb.AppendLine(scalar.ScalarValue);
                    else
                        sb.AppendLine("[NULL]");
                    if (string.IsNullOrEmpty(scalar.ExportedFileName) == false)
                    {
                        sb.Append("  Exported file: ");
                        sb.AppendLine(scalar.ExportedFileName);
                    }
                    sb.AppendLine();

                }
                #endregion

                #region iterate each out-type cursor argument

                foreach (var recordset in item.ListRecordsetExecutionResult)
                {
                    sb.Append("Cursor argument: ");
                    sb.AppendLine(recordset.Argument.Name);
                    sb.Append("  Record count: ");
                    sb.AppendLine(recordset.XElmtRecords.Count.ToString());
                    sb.Append("  Fetch time (milliseconds): ");
                    sb.AppendLine(recordset.FetchDataMilliseconds.ToString());
                    if (string.IsNullOrEmpty(recordset.ExportedFileName) == false)
                    {
                        sb.Append("  Exported file: ");
                        sb.AppendLine(recordset.ExportedFileName);
                    }
                    sb.AppendLine();
                }

                #endregion
  
            }
            return sb.ToString();
        }
    }
}
